<?php
/**
 * 企业内部信息调用接口。通过企业内部开发文档调用接口
 */
namespace app\msgapi\service;

use think\facade\Cache;
use app\utils\Http;
use think\facade\Log;

error_reporting(E_ERROR | E_PARSE);
class WeworkCorpSelfService
{
    private $corpid;            //企业corpid
    private $staff_secret;      //通讯录密钥secret
    private $customer_secret;   //客户密钥secret
    private $msg_secret;        //存档密钥secret
    private $agent_id;          //自建应用agent_id
    private $agent_secret;      //自建应用secret

    private Http $http;

    public function __construct()
    {
        $corpInfo = HscorpInfoService::getCorpInfo(env('wework.corpid'),true); //获取企业密钥信息
        $this->corpid = $corpInfo['corp_info']['corpid'];
        $this->staff_secret = $corpInfo['corp_info']['address_book_secret'];
        $this->customer_secret = $corpInfo['corp_info']['customer_secret'];
        $this->msg_secret = $corpInfo['corp_info']['msg_secret'];
        $this->agent_id = $corpInfo['corp_info']['agent_id'];
        $this->agent_secret = $corpInfo['corp_info']['agent_secret'];
        $this->http = app()->make(Http::class, [[]]);
    }

    /**获取部门列表，递归获取所有子部门列表
     * @param string $id 部门id
     * @return array|bool|mixed|string
     * @throws \Exception
     */
    public function getDepartmentList($id = '')
    {
        $url = "department/list";
        $res = $this->common($url, 'get', ['id' => $id], 'staff');
        return $res;
    }

    /**根据部门获取成员(详情)列表
     * @param int $departmentid 部门id
     * @param int $fetch_child 递归获取子部门
     * @return array|bool|mixed|string
     * @throws \Exception
     */
    public function getUserListByDepartment($departmentid = 1, $fetch_child = 1)
    {
        $url = "user/list";
        $res = $this->common($url, 'get', ['department_id' => $departmentid, 'fetch_child' => $fetch_child], 'staff');
        return $res;
    }

    /**更新企业微信成员信息
     * @param array $param
     * @return array|bool|mixed|string
     * @throws \Exception
     */
    public function editUser(array $param)
    {
        $url = "user/update";
        $res = $this->common($url, 'post', $param, 'staff_edit');
        return $res;
    }

    /**获取开启存档成员列表
     * @param int $type 1办公版2服务版3企业版
     * @return array|bool|mixed|string
     * @throws \Exception
     */
    public function getPermitUserList($type = 0)
    {
        $url = "msgaudit/get_permit_user_list";
        $res = $this->common($url, 'post', ['type' => $type], 'msg');
        return $res;
    }

    /**自建应用jsticket
     * @param int $reload
     * @return mixed|string
     * @throws \Exception
     */
    public function getJsApiTicket($reload = 0)
    {
        $jsApiTicket = Cache::get('corpself_' . $this->corpid . '_jsapi_ticket');
        if (!$jsApiTicket || $reload) {
            $url = "get_jsapi_ticket";
            $res = $this->common($url, 'get', [], 'agent');
            if (isset($res['ticket'])) {
                $jsApiTicket = $res['ticket'];
                Cache::set($this->corpid . '_jsapi_ticket', $res['ticket'], $res['expires_in'] - 200);
            }
        }
        return $jsApiTicket;
    }

    /**自建应用应用ticket
     * @param int $reload
     * @return mixed|string
     * @throws \Exception
     */
    public function getAgentJsApiTicket($reload = 0)
    {
        $jsApiTicket = Cache::get($this->corpid . '_agent_jsapi_ticket');
        if (!$jsApiTicket || $reload) {
            $url = "ticket/get";
            $res = $this->common($url, 'get', ['type' => 'agent_config'], 'agent');
            if (isset($res['ticket'])) {
                $jsApiTicket = $res['ticket'];
                Cache::set($this->corpid . '_agent_jsapi_ticket', $res['ticket'], $res['expires_in'] - 200);
            }
        }
        return $jsApiTicket;
    }

    /**批量获取外部客户详情
     * @param string $userid 用户id
     * @param string $cursor 分页游标
     * @param int $limit 返回记录数
     * @return array|bool|mixed|string
     * @throws \Exception
     */
    public function getCustomerBath(string $userid,$cursor='',$limit = 100){
        $url = "externalcontact/batch/get_by_user";
        return $this->common($url,'post',['userid'=>$userid,'cursor'=>$cursor,'limit'=>$limit],'customer');
    }
    /**获取内部群详情
     * @param string $rommid
     * @return array|bool|mixed|string
     * @throws \Exception
     */
    public function getInnerGroupInfo($rommid = '')
    {
        $url = "msgaudit/groupchat/get";
        $res = $this->common($url, 'post', ['roomid' => $rommid], 'msg');
        return $res;
    }

    /**获取外部群信息
     * @param string $roomid
     * @return array|bool|mixed|string
     * @throws \Exception
     */
    public function getOutGroupInfo($roomid = '')
    {
        $url = "externalcontact/groupchat/get";
        $data = ['chat_id' => $roomid];
        return $this->common($url, 'post', $data, 'customer');
    }

    /**获取外部联系群组的列表
     * @param $userlist
     * @param string $cursor
     * @param int $limit
     * @return array|bool|mixed|string
     * @throws \Exception
     */
    public function getOutGroupList($userlist,$cursor='',$limit=1000){
        $url = 'externalcontact/groupchat/list';
        $data = [
            'status_filter'=>0,
            'owner_filter'=>['userid_list'=>$userlist],
            'cursor'=>$cursor,
            'limit'=>$limit
        ];
        return $this->common($url,'post',$data,'customer');
    }

    /**获取外部联系人信息
     * @param $external_userid
     * @return array|bool|mixed|string
     * @throws \Exception
     */
    public function getExternalUserInfo($external_userid)
    {
        $url = "externalcontact/get";
        $data = ['external_userid' => $external_userid];
        return $this->common($url, 'get', $data, 'customer');
    }

    /**发送订阅消息
     * @param $tosuer
     * @param $mstype
     * @param $content
     * @param int $enable_duplicate_check
     * @return array|bool|mixed|string
     * @throws \Exception
     */
    public function sendTempMessage($tosuer,$mstype,$content,$enable_duplicate_check=1){
        $tosuer = implode('|',$tosuer);
        if($tosuer){
            $data = [
                'touser'=>$tosuer,
                'msgtype'=>$mstype,
                'agentid'=>$this->agent_id,
                $mstype=>['content'=>$content],
                'enable_duplicate_check'=>$enable_duplicate_check
            ];
            $url = "message/send";
            return $this->common($url,'post',$data,'agent');
        }
    }

    /** 公共接口
     * @param $url
     * @param $method
     * @param $Param
     * @param $type string 通讯录接口staff  客户接口customer  存档接口msg
     * @param int $reload
     * @param int $times
     * @return array|bool|mixed|string
     * @throws \Exception
     */
    public function common($url, $method, $Param, $type = 'staff', $reload = 0)
    {
        $url = "https://qyapi.weixin.qq.com/cgi-bin/" . $url . '?access_token=' . $this->getAccessToken($type, $reload);
        if ($method == 'get') {
            $html = [];
            foreach ($Param as $k => $v) {
                if ($v) {
                    $html [] = "{$k}={$v}";
                }
            }
            if ($html) {
                $url .= '&' . implode('&', $html);
            }

            $res = $this->http->request('GET',$url);
        } else {
            $res = $this->http->request('POST',$url,$Param);
        }
        if ($res['errcode'] == '40014') {
            $this->common($url, $method, $Param, $type, 1);
        }
        return $res;
    }
    

    /**
     * @param string $type 类型 staff通讯录非修改操作(用应用secret) customer客户  msg会话存档 agent自建应用  staff_edit通讯录编辑操作
     * @param int $reload
     * @return mixed
     * @throws \Exception
     */
    public function getAccessToken($type = 'staff', $reload = 0)
    {
        $accessToken = Cache::get($type . '_access_token');
        if (!$accessToken || $reload == 1) {
            $array = [
                'staff' => $this->agent_secret,
                'customer' => $this->customer_secret,
                'msg' => $this->msg_secret,
                'agent' => $this->agent_secret,
                'staff_edit' => $this->staff_secret, //通讯录修改用
            ];
            $url = "https://qyapi.weixin.qq.com/cgi-bin/gettoken?corpid={$this->corpid}&corpsecret=" . $array[$type];
            $res = $this->http->request('GET',$url);
            if ($res['errcode'] == 0) {
                $accessToken = $res['access_token'];
                Cache::set($type . '_access_token', $accessToken, $res['expires_in'] - 200);
            }
        }
        return $accessToken;
    }
}